SERVERS = {}

ORGAN = {}

ORG_CENTRALIZED = 0
ORG_DECENTRALIZED = 1

ORG_INTERNAL_SERVICES = 0
ORG_MAINFRAME = 1
-- Add businesses
if SERVER then
	if not MISSION_VARIABLES_STORE then -- This should be loaded by now, but just incase...
		MISSION_VARIABLES_STORE = {}
		MISSION_VARIABLES_STORE.Business = string.Explode("\n",file.Read("shadow/corporations.txt"))
		MISSION_VARIABLES_STORE.FName = string.Explode("\n",file.Read("shadow/fnames.txt"))
		MISSION_VARIABLES_STORE.LName = string.Explode("\n",file.Read("shadow/lnames.txt"))
	end
	
	function GeneratePassword(diff)
		local core = math.Interpolate(1,MAX_DIFFICULTY,MIN_PASSWORD_LENGTH,MAX_PASSWORD_LENGTH,diff)
		
		local leeway = 1 + math.Rand(-PASSWORD_LEEWAY_PERCENTILE,PASSWORD_LEEWAY_PERCENTILE)
		
		local plen = math.Round(core*leeway)
		
		local str=""
		
		local blacklist = {[["]],[[']],"[","]",[[%]]}
		
		for i=1,plen do
			local char = string.char(math.random(PASSWORD_CHARS[1],PASSWORD_CHARS[2]))
			for j=1,6 do -- We really do not want any of those blacklisted characters, because they can fuck things up.
				if not table.HasValue(blacklist,char) then
					break
				else
					char = string.char(math.random(PASSWORD_CHARS[1],PASSWORD_CHARS[2]))
				end
			end
			
			str = str..char
		end
		
		return str
	end
	
	function GenerateNumberString(vals)
		local str = ""
		for i=1,vals do
			str = str..math.random(0,9)
		end
		return str
	end
	
	function GenerateIPAddress()
		local segs = {}
		for i=1,4 do
			table.insert(segs,GenerateNumberString(math.random(2,3)))
		end
		
		return table.concat(segs,".")
	end
	
	function CreateServer(bus,vals)
		local t = table.Copy(vals)
		
		t.Organization = bus
		t.IPAddress = GenerateIPAddress()
		
		ORGAN[bus].Servers[t.IPAddress] = t
		
		return t.IPAddress
	end
	
	function GenerateEmployees(diff)
		local t = {}
		local c = 0
		
		for i=1,diff do
			c=c+math.random(ORG_EMPS_PER_SEC[1],ORG_EMPS_PER_SEC[2])
		end
		
		for i=1,c do
			table.insert(t,{table.Random(MISSION_VARIABLES_STORE.FName),table.Random(MISSION_VARIABLES_STORE.LName)})
		end
		
		return t
	end
	
	function GenerateFiles(bus,diff)
		local t = {}
		local c = 0
		
		for i=1,diff do
			c=c+math.random(ORG_FILES_PER_SEC[1],ORG_FILES_PER_SEC[2])
		end
		
		for i=1,c do
			table.insert(t,GenerateFile(bus))
		end
		
		return t
	end
	
	function GetServerFromType(bus,typ)
		local t = {}
		for ip,info in pairs(ORGAN[bus].Servers) do
			if info.Structure==typ then
				table.insert(t,ip)
			end
		end
		
		return table.Random(t)
	end
	
	function GenerateOrganizations()
		ORGAN = {}
		-- Generate businesses first
		for k,name in pairs(MISSION_VARIABLES_STORE.Business) do
			local t = {}
			t.Personality = EMAIL_CORPORATE -- Translates to personality type
			t.Difficulty = math.random(MAX_DIFFICULTY) -- Translates to difficulty
			t.Servers = {} -- A list of all the servers this business has.
			t.CorpName = name
			
			if t.Difficulty<ORG_MIN_DECEN then
				t.ServerType = ORG_CENTRALIZED
			elseif t.Difficulty>ORG_MAX_CEN then
				t.ServerType = ORG_DECENTRALIZED
			else
				t.ServerType = table.Random({ORG_CENTRALIZED,ORG_DECENTRALIZED})
			end
			
			-- Set up the servers
			timer.Simple(0.1,function()
				-- Centralized
				if t.ServerType==ORG_CENTRALIZED then
					-- Generate the central mainframe
					local diff = t.Difficulty + math.Round(t.Difficulty * math.Rand(-ORG_SERVER_SECURITY_RANGE_CEN,ORG_SERVER_SECURITY_RANGE_CEN))
					local mainframe = CreateServer(name,{
						Name=name.." Central Mainframe",
						Security=diff,
						Employees=GenerateEmployees(diff),
						Files=GenerateFiles(name,diff),
						Private=true, -- Private means that it can only be accessed through another terminal owned by the company.
						Administrator={table.Random(MISSION_VARIABLES_STORE.FName),table.Random(MISSION_VARIABLES_STORE.LName)},
						AdminPassword=GeneratePassword(diff),
						Structure=ORG_MAINFRAME}
					)
					
					-- Generate the internal services
					local diff = t.Difficulty + math.Round(t.Difficulty * math.Rand(-ORG_SERVER_SECURITY_RANGE_CEN,ORG_SERVER_SECURITY_RANGE_CEN))
					CreateServer(name,{
						Name=name.." Internal Services",
						Security=diff,
						Employees=GenerateEmployees(diff),
						Administrator={table.Random(MISSION_VARIABLES_STORE.FName),table.Random(MISSION_VARIABLES_STORE.LName)},
						AdminPassword=GeneratePassword(diff),
						MainframeAddress=mainframe,
						Structure=ORG_INTERNAL_SERVICES}
					)
				end
				
				-- Decentralized
				if t.ServerType==ORG_DECENTRALIZED then
					-- TODO: MAKE US WHOLE AGAIN, ISAAC!
					
					CreateServer(name,{Name="Blah",Employees=GenerateEmployees(1),Structure=ORG_INTERNAL_SERVICES})
					CreateServer(name,{Name="Blah2",Employees=GenerateEmployees(1),Structure=ORG_MAINFRAME,Files={"Hi"}})
				end
			end)
			
			ORGAN[name] = t
		end
	end
	
	GenerateOrganizations()
end
		